import asyncio
import json
import os

from .atomgit import Atomgit
from .payload import Payload
from .pipeline import Pipeline

class UnsupportedRepoError(IOError):
    pass

class EventHander(object):
    def __init__(self, payload, config_dir=None):
        self.payload = payload
        self.config_dir = config_dir
        self.repo_config = Payload(self.load_repo_config())

    def load_repo_config(self):
        (org, repo) = self.payload['repository', 'full_name'].split('/')
        try:
            return self._load_json_file(os.path.join(org, repo) + '.json')
        except IOError:
            print('加载流水线配置失败')
            raise UnsupportedRepoError
    
    def _load_json_file(self, name):
        config_dir = self.config_dir
        if not self.config_dir:
            config_dir = os.path.join(os.path.dirname(__file__), 'configs')
        with open(os.path.join(config_dir, name)) as config:
            return json.load(config)

    def run(self, event, config):
        # 找具体仓库对应的流水线 如果没有报错，如果有把结果输出成 Atomgit 认识的形式。
        print("收到 webhook, 处理中...")
        if event == "ping":
            return "Ping received!\n"
        elif event == "pull_requests" and (self.payload['action'] == "opened" or self.payload['action'] == "synchronized"):
            self.handle_mr(config)
            return 'OK, handled new PR\n'
        else:
            return 'Unsupported webhook event.\n'
    
    def handle_mr(self, config):
        pipeline = Pipeline(config)
        pipeline_run_id = Payload(pipeline.run_pipeline(self.payload, self.repo_config).json())['pipeline_run_id']
        
        # 使用asyncio库中的run方法来运行异步函数
        pipeline_detail = Payload(pipeline.show_pipeline_detail(
            repo_config=self.repo_config, 
            pipeline_run_id=pipeline_run_id
            ).json())
        print('创建自动化检测...')
        check_run_id = Atomgit(
            config=config, 
            payload=self.payload, 
            pipeline_detail=pipeline_detail
            ).create().json().get('id')
        asyncio.run(track_pipeline_completion(
            config=config, 
            payload=self.payload, 
            repo_config=self.repo_config, 
            pipeline_run_id=pipeline_run_id, 
            check_run_id=check_run_id
            ))

async def track_pipeline_completion(config, payload, repo_config, pipeline_run_id, check_run_id):
    while True:
        pipeline_detail = Payload(Pipeline(config).show_pipeline_detail(repo_config, pipeline_run_id).json())
        if pipeline_detail['end_time'] is not None:
            if pipeline_detail['status'] == "COMPLETED" or pipeline_detail['status'] == "FAILED" or pipeline_detail['status'] == "CANCELED":
                print('更新自动化检测...', check_run_id)
                Atomgit(config=config, payload=payload, pipeline_detail=pipeline_detail).update(check_run_id=check_run_id)
                print('更新自动化检测...done')
                return None
        else:
            print("Pipeline 尚未完成，正在等待...")
            await asyncio.sleep(1) # 每秒检测一次